<template>
  <div :tabindex="-1" class="canvas-container" ref="canvas_container">
    <canvas id="canvas"></canvas>
  </div>
</template>
<script setup lang="ts" name="">
import { ref } from "vue";
import { fabric } from "fabric";
import { publicUrl } from "@/utils/util";
import { toast } from "vue3-toastify";
import { useElementSize, watchThrottled } from "@vueuse/core";

var canvas: null | fabric.Canvas = null;

var imgWidth: number = 0; //图片宽度

var imgHeight: number = 0; //图片高度

var ratio: number = 0; //宽高比

const canvas_container = ref(null);

const { width: canvasWidth } = useElementSize(canvas_container);

// onClickOutside(canvas_container, () =>
//   canvas ? emits("handleBlur") : undefined
// );

watchThrottled(
  canvasWidth,
  (newValue) => {
    if (canvas) {
      canvas.setWidth(newValue);
      canvas.setHeight(newValue / ratio);
      canvas.setZoom(newValue / imgWidth);
    } else {
      init();
    }
  },
  { throttle: 500 }
);
function showkey(event: KeyboardEvent) {
  var e = event || window.event;
  var keyCode = e.keyCode || e.which;
  switch (keyCode) {
    case 46: //"按了delete键！"
      if (canvas) {
        let act = canvas.getActiveObject();
        if (act) {
          canvas.remove(act);
          toast.info(`移除成功`);
          setTimeout(() => emits("handleBlur"), 500);
        }
      }
      break;
  }
}

document.onkeydown = showkey;

const init = () => {
  fabric.Image.fromURL(
    publicUrl(`/images/poster.jpg`),
    (image: fabric.Image) => {
      imgWidth = image.width as number;
      imgHeight = image.height as number;
      ratio = imgWidth / imgHeight;
      canvas = new fabric.Canvas("canvas", {
        width: canvasWidth.value,
        height: canvasWidth.value / ratio,
      });

      canvas.setBackgroundImage(image, canvas.renderAll.bind(canvas));

      canvas.setZoom(canvasWidth.value / imgWidth);

      canvas.on("object:modified", function () {
        setTimeout(() => emits("handleBlur"), 500);
      });
    }
  );
};

const addText = (color: string, text: string) => {
  if (!canvas) return toast.info(`图片暂未生成请稍等`);
  canvas.add(
    new fabric.IText(text, {
      width: 300,
      fontSize: 14,
      //   fontFamily: "Comic Sans",
      left: 50,
      top: 100,
      fill: color,
    })
  );
  setTimeout(() => emits("handleBlur"), 500);
};
const emits = defineEmits<{
  (event: "handleBlur"): void;
}>();

const addImg = (toUrl: string) => {
  if (!canvas) return toast.info(`海报暂未生成请稍等`);
  fabric.Image.fromURL(toUrl, (oImg) => {
    oImg.scale(0.5).set("flipX", true);
    if (canvas) {
      canvas.add(oImg);
      setTimeout(() => emits("handleBlur"), 500);
    }
  });
};

const canvasClone = () =>
  new Promise<string>((res) => {
    canvas?.clone((item: any) => {
      item.setZoom(1);
      res(
        item.toDataURL({
          format: "png",
          left: 0,
          top: 0,
          width: imgWidth,
          height: imgHeight,
        })
      );
    });
  });

const createImg = async (): Promise<string | void> => {
  if (!canvas) toast.info(`海报暂未生成请稍等`);
  else return await canvasClone();
};

defineExpose({ addText, addImg, createImg });
</script>
<style scoped lang="scss">
@import "./index.scss";
</style>
